package cc.linker.steplink.crm.task;

import cc.linker.steplink.crm.commons.Constants;
import cc.linker.steplink.crm.commons.form.FormRequest;
import cc.linker.steplink.crm.commons.lock.RedisLock;
import cc.linker.steplink.crm.commons.model.FormLoginDto;
import cc.linker.steplink.crm.dao.AutoMarkLabelDao;
import cc.linker.steplink.crm.domain.Label;
import cc.linker.steplink.crm.merchant.dao.EnrollDao;
import cc.linker.steplink.crm.merchanth5.commons.FormFilter;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 自动打标签
 */
@Slf4j
@RestController
public class AutoMarkLabelTask {
    @Autowired
    private AutoMarkLabelDao autoMarkLabelDao;
    @Autowired
    private EnrollDao enrollDao;
    @Autowired
    private FormFilter formFilter;
    @Autowired
    private FormRequest formRequest;
    
    private final static SimpleDateFormat DAY_FORMAT = new SimpleDateFormat("yyyy-MM-dd");

    /**
     * 手动调用
     */
    @GetMapping("/autoMarkLabelTaskToDo")
    @ResponseBody
    public String updateAccountMoneyDayTasksToDo(){
        work();
        return "ok";
    }


    @RedisLock("AutoMarkLabelTask")
    @Scheduled(cron = "0 0 1 * * ?")
    public void work(){
        // 查询自动标签规则
//        List<Label> labels = autoMarkLabelDao.listLabelsByTypeAndKind(Constants.LABEL_TYPE, Constants.LABEL_KIND_AUTO);
        List<Label> labels = autoMarkLabelDao.AutolistLabels();
        if (labels == null || labels.isEmpty()) {
            return;
        }
        rules : for (Label item : labels) {
            if (StringUtils.isEmpty(item.getAutoSetup())) {
                continue;
            }
            String labelId = item.getLabelId();
            String labelName = item.getLabelName();
            String orgId = item.getOrgId();

            // 目标用户集合
            Set<String> goals = new HashSet<>();
            
//            String autoSetup = "{ \"type\" : \"0\" , \"behaviorList\" : [ { \"key\" : 1 , \"value\" : \"1,5\"} , " +
//                    "{ \"key\" : 2 , \"value\" : \"2,7\"} , { \"key\" : 3 , \"value\" : { \"type\" : 0 , " +
//                    "\"num\" : 7 , \"dates\" : \"\"}}] , \"userBaseList\" : [ { \"key\" : 1 , \"value\" : \"1\"}]}\n";
//            JSONObject jsonObject = JSON.parseObject(autoSetup);
            JSONObject jsonObject = JSON.parseObject(item.getAutoSetup());
            JSONArray behaviorList = jsonObject.getJSONArray("behaviorList");
            JSONArray userBaseList = jsonObject.getJSONArray("userBaseList");
            // 0 满足任意条件 1 满足所有
            Boolean conditionType = jsonObject.getBoolean("type");
            List<String> customerIds1 = new ArrayList<>();
            List<String> customerIds2 = new ArrayList<>();
            List<String> customerIds3 = new ArrayList<>();
            List<String> customerIds4 = new ArrayList<>();
            List<List<String>> newCustomerIds = new ArrayList<>();
            List<Integer> keyList = new ArrayList<>();
            for (Object behavior : behaviorList) {
                JSONObject jo = (JSONObject)behavior;
                Integer type = jo.getInteger("key");
                String value = jo.getString("value");
                List<String> customerIds = new ArrayList<>();
                if (StringUtils.isEmpty(value)) {
                    continue;
                }
                keyList.add(type);
                if (type == 1) {
                    String[] values = value.split(",");
                    if (values.length != 2) {
                        LOGGER.warn("自动标签规则[{}]{}有误，跳过此规则", labelId, labelName);
                        continue rules;
                    }
                    // 累计对话
                    customerIds1 = autoMarkLabelDao.listCustomerIdByType(Constants.ACTION_TYPE_IDP_TALK, 
                            values[0], values[1], orgId);
                    if("0".equals(values[0])){
                        //获取没有对话的
                        List<String> customerIds12 = autoMarkLabelDao.listCustomerIdByTyp0(Constants.ACTION_TYPE_IDP_TALK,orgId);
                        customerIds1.addAll(customerIds12);
                    }
                    customerIds = customerIds1;
                } else if(type == 2) {
                    // 累计访问
                    String[] values = value.split(",");
                    if (values.length != 2) {
                        LOGGER.warn("自动标签规则[{}]{}有误，跳过此规则", labelId, labelName);
                        continue rules;
                    }
                    customerIds2 = autoMarkLabelDao.listCustomerIdByType(Constants.ACTION_TYPE_H5_VISIT, 
                            values[0], values[1], orgId);
                    if("0".equals(values[0])){
                        //获取没有对话的
                        List<String> customerIds22 = autoMarkLabelDao.listCustomerIdByTyp0(Constants.ACTION_TYPE_IDP_TALK,orgId);
                        customerIds2.addAll(customerIds22);
                    }
                    customerIds = customerIds2;
                } else if(type == 3) {
                    // 累计关注
                    JSONObject subJson = jo.getJSONObject("value");
                    Date[] dates = new Date[2];
                    // 0 最近 1 自定义
                    Boolean dateType = subJson.getBoolean("type");
                    if (!dateType) {
                        Integer days = subJson.getInteger("num");
                        Calendar calendar = Calendar.getInstance();
                        dates[1] = calendar.getTime();
                        calendar.add(Calendar.DAY_OF_MONTH, 0 - days);
                        dates[0] = calendar.getTime();
                    } else {
                        try {
                            JSONArray dateArr = subJson.getJSONArray("dates");
                            if (dateArr == null || dateArr.size() != 2) {
                                LOGGER.warn("自动标签规则[{}]{}有误，跳过此规则", labelId, labelName);
                                continue;
                            }
                            dates[0] = DAY_FORMAT.parse(dateArr.getString(0));
                            dates[1] = DAY_FORMAT.parse(dateArr.getString(1));
                        } catch (ParseException e) {
                            LOGGER.error(e.getMessage());
                            LOGGER.warn("自动标签规则[{}]{}有误，跳过此规则", labelId, labelName);
                            continue rules;
                        }
                    }
//                    customerIds3 = autoMarkLabelDao.listCustomerIdByTypeAndTime(Constants.ACTION_TYPE_IDP_FOLLOW,
//                            dates[0], dates[1], orgId);
                    customerIds3 = autoMarkLabelDao.listCustomerIdByTime(dates[0], dates[1], orgId);
                    customerIds = customerIds3;
                }else if(type == 4){
                    //老报名
                    JSONObject subJson = jo.getJSONObject("value");
                    String enrollId= subJson.getString("enrollId");
                    String attrId= subJson.getString("attrId");
                    String itemName= subJson.getString("itemName");

                    List<String> customerIdsE = new ArrayList<>();

                    Map paraMap = new HashMap();
                    paraMap.put("enrollId",enrollId);
                    List<Map<String, Object>> res = enrollDao.recordList(paraMap);
                    res.forEach(x->{
                        if(StringUtils.isEmpty(attrId)){
                            if(!StringUtils.isEmpty(x.get("customerId"))){
                                customerIdsE.add(x.get("customerId").toString());
                            }
                        }
                        if(!StringUtils.isEmpty(x.get("record"))) {
                            String recordListString =  x.get("record").toString();
                            List<Map<String,String>> recordList = JSONArray.parseObject(recordListString,List.class);
                                recordList.forEach(y->{
                                    if(!StringUtils.isEmpty(y.get("attrId"))){
                                        String attrIdE = y.get("attrId").toString();
                                        if(attrId.equals(attrIdE)){
                                            if(!StringUtils.isEmpty(y.get("attrValue"))){
                                                String attrValue = y.get("attrValue").toString();
                                                String itemNames[] = attrValue.split("\\|");
                                                if(itemNames!=null && itemNames.length>0){
                                                    for(String itemNameE : itemNames){
                                                        if(!StringUtils.isEmpty(itemName)){
                                                            if(itemName.equals(itemNameE)){
                                                                customerIdsE.add(x.get("customerId").toString());
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                });
                        }
                    });
                    newCustomerIds.add(customerIdsE);
                }else if(type == 5){
                    //新表单
                    JSONObject subJson = jo.getJSONObject("value");
                    String formId= subJson.getString("formId");
                    String attrId= subJson.getString("attrId");
                    String itemId= subJson.getString("itemId");
                    LOGGER.info("自动打标签表单参数---》"+"formId:"+formId+"  attrId:"+attrId+"  itemId:"+itemId);
                    List<String> customerIdsF = new ArrayList<>();
                    List<Map<String, Object>> res = this.getFormRecode(formId,orgId);
                    LOGGER.info("自动打标签表单报名列表---》"+JSON.toJSONString(res));
                    res.forEach(x->{
                        if(StringUtils.isEmpty(attrId)){
                            if(!StringUtils.isEmpty(x.get("customerId"))){
                                customerIdsF.add(x.get("customerId").toString());
                                LOGGER.info("自动打标签表单参数符合条件人---》"+x.get("customerId").toString());
                            }
                        }
                        if(!StringUtils.isEmpty(x.get("recordInfoMap"))) {
                            Map<String, Object> recordMap = (Map) x.get("recordInfoMap");
                            List<Map<String, Object>> recordList =  getLikeByMap(recordMap);
                                recordList.forEach(y->{
                                    if(!StringUtils.isEmpty(y.get("attrId"))){
                                        String attrIdE = y.get("attrId").toString();
                                        if(attrId.equals(attrIdE)){
                                            if(!StringUtils.isEmpty(y.get("attrValue"))){
                                                String attrValue = y.get("attrValue").toString();
                                                String itemIds[] = attrValue.split(",");
                                                if(itemIds!=null && itemIds.length>0){
                                                    for(String itemIdF : itemIds){
                                                        if(!StringUtils.isEmpty(itemIdF)){
                                                            if(itemId.equals(itemIdF)){
                                                                customerIdsF.add(x.get("customerId").toString());
                                                                LOGGER.info("自动打标签表单参数符合条件人---》"+x.get("customerId").toString());
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                });
                        }
                    });
                    newCustomerIds.add(customerIdsF);
                }
                
                if (!conditionType) {
                    // 满足任意条件
                    goals.addAll(customerIds);
                } else {
                    if (customerIds.isEmpty() && newCustomerIds.size()==0) {
                        LOGGER.debug("自动标签规则[{}]{}符合条件用户集为空，跳过此规则", labelId, labelName);
                        continue rules;
                    }
                }
            }
            Integer gender = null;
            String area = null;
            String areaOther = null;
            for (Object behavior : userBaseList) {
                JSONObject jo = (JSONObject)behavior;
                // 
                Integer type = jo.getInteger("key");
                String value = jo.getString("value");
                if (type == 1) {
                    // 性别
                    gender = "1".equals(value) ? 1 : ("0".equals(value) ? 0 : 2);
                } else if(type == 2) {
                    // 地区 浙江省@杭州市@萧山区 -> 浙江杭州萧山
                    if (!StringUtils.isEmpty(value)) {
                        String[] regions = value.split(",");
                        if (regions.length > 0) {
                            for (String region : regions) {
                                if (region.length() > 0) {
                                    area = "" + region.substring(0, region.length()-1);
                                }
                            }
                        }
                        area = value.replaceAll(",", "");
                        area = area.replaceAll("省","");
                        area = area.replaceAll("市","");
                    }
                    if (!StringUtils.isEmpty(value)) {
                        String[] regions = value.split(",");
                        if (regions.length > 0) {
                            for (String region : regions) {
                                if (region.length() > 0) {
                                    areaOther = "" + region.substring(0, region.length()-1);
                                }
                            }
                        }
                        areaOther = value.replaceAll(",", "@");
                        areaOther = areaOther.replaceAll("省","");
                        areaOther = areaOther.replaceAll("市","");
                    }
                } else {
                    LOGGER.warn("自动标签规则[{}]{}有误，跳过此规则", labelId, labelName);
                    continue rules;
                }
            }
            if (gender != null || area!= null) {
                keyList.add(6);
                if (!conditionType) {
                    if (area != null) {
                        customerIds4 = autoMarkLabelDao.listCustomerIdOrCustomerAttributes(gender, area, orgId,areaOther);
                    } else {
                        customerIds4 = autoMarkLabelDao.listCustomerIdOrCustomerAttributes(gender, null, orgId,null);
                    }
                } else {
                    if (area != null) {
                        customerIds4 = autoMarkLabelDao.listCustomerIdAndCustomerAttributes(gender, area, orgId,areaOther);
                    } else {
                        customerIds4 = autoMarkLabelDao.listCustomerIdAndCustomerAttributes(gender, null, orgId,null);
                    }
                    if (customerIds4.isEmpty()) {
                        LOGGER.debug("自动标签规则[{}]{}符合条件用户集为空，跳过此规则", labelId, labelName);
                        continue rules;
                    }
                }
            }
            if (conditionType) {
                // 满足所有条件，求交集
                if( keyList.contains(1)){
                    goals.addAll(customerIds1);
                }
                if( keyList.contains(2)) {
                    if (keyList.contains(1)) {
                        goals.retainAll(customerIds2);
                    } else {
                        goals.addAll(customerIds2);
                    }
                }
                if( keyList.contains(3)) {
                    if(keyList.contains(1) || keyList.contains(2)){
                        goals.retainAll(customerIds3);
                    }else {
                        goals.addAll(customerIds3);
                    }
                }
                if( keyList.contains(4) || keyList.contains(5)) {
                    if(keyList.contains(1) || keyList.contains(2) || keyList.contains(3)){
                        for(List<String> newCustomerId : newCustomerIds){
                            goals.retainAll(newCustomerId);
                        }
                    }else {
                        for(int i=0;i<newCustomerIds.size();i++){
                            if(i==0){
                                goals.addAll(newCustomerIds.get(i));
                            }else {
                                goals.retainAll(newCustomerIds.get(i));
                            }
                        }
                    }
                }
                if( keyList.contains(6)) {
                    if (keyList.contains(1) || keyList.contains(2) || keyList.contains(3) || keyList.contains(4) || keyList.contains(5)) {
                        goals.retainAll(customerIds4);
                    } else {
                        goals.addAll(customerIds4);
                    }
                }
            } else {
                // 满足任意条件，求并集
                goals.addAll(customerIds1);
                goals.addAll(customerIds2);
                goals.addAll(customerIds3);
                goals.addAll(customerIds4);
                for(List<String> newCustomerId : newCustomerIds){
                    goals.addAll(newCustomerId);
                }
            }
            
            // 打标签
            if (goals.size() > 0) {
                LOGGER.info("多次批量打标签");
                if (goals.size() <= 1000) {
                    autoMarkLabelDao.insertCustomerLabelsBatch(goals, labelId);
                } else {
                    Iterator<String> it = goals.iterator();
                    List<String> tempList = new LinkedList<String>();
                    int count = 0;
                    while (it.hasNext()) {
                        String temp = it.next();
                        tempList.add(temp);
                        count++;
                        if (tempList.size() >= 1000) {
                            autoMarkLabelDao.insertCustomerLabelsBatch(goals, labelId);
                            tempList.clear();
                        } else {
                            if (!it.hasNext()) {
                                autoMarkLabelDao.insertCustomerLabelsBatch(goals, labelId);
                            }
                        }
                    }
                }
            }
        }
        
    }

    @GetMapping("/getFormRecode2")
    public List<Map<String, Object>> getFormRecode(String formId,String orgId){
        FormLoginDto formLoginDto = FormLoginDto.builder()
                .customerId(orgId)
                .customerPhone("")
                .orgId(orgId)
                .isOrgAccount(0)
                .customerName("")
                .wxOpenId("")
                .wxToken("")
                .storeName("").build();
        Map params = new HashMap();
        params.put("formId",formId);
        List<Map<String, Object>> mapList = new ArrayList<>();
        try {
            List<Map<String, Object>> mapList1 =   (List<Map<String, Object>>)  formRequest.doRequest("/pc/form/record/recordAlllist", params, formLoginDto);
            if(mapList1!=null && mapList1.size()>0){
                mapList = mapList1;
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return mapList;
    }

    @GetMapping("/getFormRecode")
    public List<String>  getFormRecodes(@RequestParam String formId, @RequestParam String orgId, @RequestParam String attrId, @RequestParam String itemId){
        //新表单

        List<String> customerIdsF = new ArrayList<>();
        List<Map<String, Object>> res = this.getFormRecode(formId,orgId);
        res.forEach(x->{
            if(StringUtils.isEmpty(attrId)){
                if(!StringUtils.isEmpty(x.get("customerId"))){
                    customerIdsF.add(x.get("customerId").toString());
                }
            }
            if(!StringUtils.isEmpty(x.get("recordInfoMap"))) {
                Map<String, Object> recordMap = (Map) x.get("recordInfoMap");
                List<Map<String, Object>> recordList =  getLikeByMap(recordMap);
                    recordList.forEach(y->{
                        if(!StringUtils.isEmpty(y.get("attrId"))){
                            String attrIdE = y.get("attrId").toString();
                            if(attrId.equals(attrIdE)){
                                if(!StringUtils.isEmpty(y.get("attrValue"))){
                                    String attrValue = y.get("attrValue").toString();
                                    String itemIds[] = attrValue.split(",");
                                    if(itemIds!=null && itemIds.length>0){
                                        for(String itemIdF : itemIds){
                                            if(!StringUtils.isEmpty(itemIdF)){
                                                if(itemId.equals(itemIdF)){
                                                    customerIdsF.add(x.get("customerId").toString());
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    });
            }
        });
        return customerIdsF;
    }

    private static List<Map<String, Object>> getLikeByMap(Map<String, Object> map) {
        if (null == map) {
            return null;
        }
        List<Map<String, Object>> list = new Vector<>();
        for (Map.Entry<String, Object> entity : map.entrySet()) {
            if (entity.getKey().contains("SELECT_") || entity.getKey().contains("RADIO_")  || entity.getKey().contains("CHECKBOX_") ) {
                Map<String, Object> tmp = new HashMap<>();
                tmp.put("attrValue", entity.getValue());
                String str = entity.getKey();
                String str1 = str.substring(0, str.indexOf("_"));
                String str2 = str.substring(str1.length() + 1);
                tmp.put("attrId", str2);
                list.add(tmp);
            }
        }
        return list;
    }
}
